#!/usr/bin/python
# -*- coding: utf-8 -*-

from PyQt4.QtGui import QFileDialog, QColor, QComboBox, QTableWidgetItem
from PyQt4.Qt import Qt
from widget.tools import MessageBox
from util.logger import warn_log as warn
from util.synchelper import GEA
from copy import deepcopy
import csv
import os


__author__ = 'xiwei'


class ROW:
    def __init__(self):
        pass

    NAME = 1
    TYPE = 2
    PREVIEW = 3


file_conf_template = {
    'file': '',
    'type': '',
    'schema': '',
    'db_increase_type': 'file'
}


class FileHandler:
    """
        Sync file that contain csv, gae etc.
        CSV file's header info is required.
    """

    file_types = [u'请选择文件类型', 'GEA', 'CSV']

    filename = None

    need_save = False

    def __init__(self, ui):
        """
            init func
        Args:
            ui (UI.App): ui

        """
        self.ui = ui

        self.file_edit = self.ui.lineEdit_file_path
        self.file_type_selector = self.ui.comboBox_file_type
        self.field_table = self.ui.tableWidget_file_preview

        self.select_color = QColor(Qt.gray)

        self.file_handler = {
            1: self.gae_handler,
            2: self.csv_handler
        }

        self.file_type_index = 0

        self.init_ui()

    def init_ui(self):
        self.field_table.setRowCount(3)
        self.field_table.setVerticalHeaderLabels([u'字段名', u'字段类型', u'预览'])

        self.file_type_selector.blockSignals(True)
        self.file_type_selector.addItems(self.file_types)
        self.file_type_selector.blockSignals(False)

    def file_select(self, filename=None):
        if filename is None:
            self.filename = u'%s' % QFileDialog().getOpenFileName()
        else:
            self.filename = filename
        self.file_edit.clear()
        self.file_edit.setText(self.filename)

    def recover_ui(self, db):
        self.file_select(db['file'])
        self.file_type_selector.setCurrentIndex(self.file_types.index(db['type']))

    def add_field(self, field):
        """
            add a field into table_widget
        Args:
            field (tuple): (preview, name) the field tuple
        """
        data_type = ['string', 'number', 'date']
        combo = QComboBox()
        combo.addItems(data_type)
        column = self.field_table.columnCount()

        self.field_table.setColumnCount(column + 1)

        self.field_table.setItem(ROW.NAME - 1, column, QTableWidgetItem(field[1]))
        self.field_table.setCellWidget(ROW.TYPE - 1, column, combo)
        self.field_table.setItem(ROW.PREVIEW - 1, column, QTableWidgetItem(field[0]))

    def table_cell_changed(self, row, col):
        """
            Something will happen when the table cell has been changed.
        Args:
            row (int): the row number of cell has been changed
            col (int): the column number of cell has been changed
        """
        pass

    def add_fields(self, headers, preview):
        for i, name in enumerate(headers):
            self.add_field((str(preview[i]), name))

    def csv_handler(self, filename):
        self.field_table.setColumnCount(0)
        if not filename or not os.path.exists(filename):
            self.need_save = False
            return
        with open(filename, 'r') as stream:
            try:
                reader = csv.reader(stream)
                if reader:
                    headers = []
                    for line in reader:
                        if not headers:
                            headers = line
                        else:
                            preview = line
                            self.add_fields(headers, preview)
                            break
                self.need_save = True
            except Exception:
                warn().warning('Parse file %s failed.Please confirm it\'s is a csv file and has header info' % filename)
                MessageBox().critical(self.ui, u'错误', u'文件解析出错, 请选择合法的csv文件.')
                self.need_save = False

    def gae_handler(self, filename):
        self.field_table.setColumnCount(0)
        try:
            gea = GEA(filename=filename)
            headers = gea.base_headers + gea.data_headers
            preview = gea.preview()[0] + gea.preview(base=False)[0]
            self.add_fields(headers, preview)
            self.need_save = True
        except OSError, e:
            warn().warning(e)
            self.need_save = False

    def gen_conf(self):
        db = file_conf_template.copy()
        db['type'] = self.file_types[self.file_type_index]
        db['file'] = self.filename
        cols = self.field_table.columnCount()
        rows = self.field_table.rowCount()
        schema = []
        for col in xrange(0, cols):
            field = {}
            for row in xrange(0, rows):
                if row + 1 == ROW.TYPE:
                    cell = self.field_table.cellWidget(row, col)
                    text = cell.currentText()
                    field['type'] = str(text)
                elif row + 1 == ROW.NAME:
                    item = self.field_table.item(row, col)
                    text = item.text()
                    field['name'] = str(text)
            schema.append(field)
        db['ds_name'] = os.path.basename(self.filename)
        db['schema'] = schema
        db['table'] = os.path.basename(self.filename)
        return db

    def file_type_changed(self, index):
        """
            Process file info when file type has been changed
        Args:
            index (int):
        """
        if not self.filename:
            self.filename = u'%s' % self.ui.lineEdit_file_path.text()
        self.file_type_index = index
        handler = self.file_handler.get(index)
        if handler:
            handler(self.filename)
